// 上传组件，支持图片/视频/文件
<template>
  <div>
    <el-upload
      class="upload-demo"
      action="#"
      v-bind="$attrs"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :before-upload="beforeUpload"
      :before-remove="beforeRemove"
      :multiple="multiple"
      :limit="limit"
      :show-file-list="showList"
      :on-exceed="handleExceed"
      :file-list="fileList"
      :disabled="disabled"
      :upload-type="uploadType"
      :auto-upload="autoUpload"
      :on-progress="handleProgress"
      :on-change="onChange"
      :accept="accept"
      :http-request="uploadFuc"
      :list-type="listType"
    >

    <!-- 视频 -->
      <template #file="{ file }" v-if="uploadType == 'video'">
        <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePictureCardPreview(file)"
          >
            <i class="el-icon-zoom-in"></i>
          </span>
          <span
            v-if="!disabled"
            class="el-upload-list__item-delete"
            @click="beforeRemove(file)"
          >
            <i class="el-icon-delete"></i>
          </span>
        </span>
        <video
          autoplay
          controls
          class="el-upload-list__item-thumbnail"
          :src="file.url"
          alt=""
        />
      </template>

    <!-- 按钮 -->
      <template v-if="uploadType == 'image' || uploadType == 'video'">
        <div class="upload_btn">
          <i class="el-icon-plus"></i>
        </div>
      </template>
      <template v-if="uploadType == 'file'">
        <el-button size="small" type="primary">点击上传</el-button>
      </template>

    <!-- 提示文字 -->
      <div slot="tip" class="el-upload__tip">
        {{ uploadTextTip }}
      </div>
    </el-upload>

    <el-dialog
      title="查看文件"
      :visible.sync="dialogVisible"
      width="50%"
      :append-to-body="true"
      :before-close="handleDialogClose"
    >
      <div v-if="dialogFile" class="dialog-content">
        <img v-if="uploadType === 'image'" :src="dialogFile.url" alt="" />
        <video v-if="uploadType === 'video'" autoplay controls>
          <source :src="dialogFile.url" />
        </video>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
import axios from 'axios'
import { getToken } from '@/utils/auth'
import router from '@/router'
export default {
  props: {
    // 文件个数限制
    limit: {
      type: Number,
      default: 9,
    },
    // 是否可以多选
    multiple: { type: Boolean, default: true },
    // 是否展示文件列表  如果是文件的话需要设置为true
    showList: { type: Boolean, default: true },
    // 文件的数组  用于初始化文件的数组
    fileList: { type: Array, default: () => [] },
    // 上传类型 目前支持 图片 image /视频 video/文件file
    uploadType: { type: String, default: "image" },
    // 文件列表的类型
    listType: { type: String, default: 'picture-card' },
    // 提示文字  默认图片类型的
    uploadTextTip: {
      type: String,
      default: "仅支持上传jpg/png文件",
    },
    // 是否禁用
    disabled: { type: Boolean, default: false },
    // 是否自动上传
    autoUpload: { type: Boolean, default: true },
     // 可以接受的文件类型,默认为所有类型
    accept: { type: String, default: '*' },
    //文件大小,单位M ，默认为空
    maxSize:{type: Number, default: 0},
    //除第一片外的其他分片切片大小（5M），此值可修改
    chunkSize:{type: Number, default: 5 * 1024 * 1024},
  },
  data() {
    return {
        dialogVisible:false,
        dialogFile:null,
        firstChunkSize: 5 * 1024 * 1024,// // 第一片分片切片大小（M），此值不可修改
        url: process.env.VUE_APP_BASE_API + 'file/api/up',
        splitUrl: process.env.VUE_APP_BASE_API + 'file/api/upload',
        showUrl: process.env.VUE_APP_BASE_API + 'file/api/download/',
        ifSplitFlag: false,//是否单文件上传还是分片上传
        // fileList: [//格式
        //   {
        //     name: "food.jpeg",
        //     url: "https://canyin.falago.cn/test/file/api/download/9229eb0991344994ac0bd94273ecaf2f",//1678437732378
        //   },
        // ],
        fileSize:0,
        fileName:'',
        fileId:'',//分片上传所用的id
        sliceSeq:0,//分片片段的长度
        tempFile:null,//分片的文件流

    };
  },
  methods: {
      handleDialogClose() {
        this.dialogFile = null
        this.dialogVisible = false
      },
      handlePictureCardPreview(file){
        this.dialogVisible = true
        this.dialogFile = file
        this.$emit('onPreview', file, this.fileList)
      },
      // 自定义上传方法
      uploadFuc(file){
          console.log('uploadFuc============',file,this.ifSplitFlag)
          if(!this.ifSplitFlag){
             this.singleLoad(file)
          }else{
            this.splitUpload(file)
          }
      },
      // 格式化文件大小显示文字
    getSize(size) {
      return size > 1024
        ? size / 1024 > 1024
          ? size / (1024 * 1024) > 1024
            ? (size / (1024 * 1024 * 1024)).toFixed(0) + 'GB'
            : (size / (1024 * 1024)).toFixed(0) + 'MB'
          : (size / 1024).toFixed(0) + 'KB'
        : size.toFixed(0) + 'B'
    },
      onChange(file, fileList){
          console.log('onChange',file, fileList)
      },
      handleProgress(event, file, fileList){
          console.log('handleProgress',event, file, fileList)
      },
      beforeUpload(file){
          console.log('beforeUpload',file);
        //   个数
          if (this.fileList.length > this.limit) {
            this.$message.warning(`当前允许上传的最大数目为${this.limit}`)
            return false
          }

        // 格式
        if (this.accept != '*') {
          const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1)
          let str = this.accept.replace(/\./g, '').split(',')
          console.log("可以接受的值为:", str);
          if (str.indexOf(fileSuffix) === -1) {
            this.$message.error('上传的文件不符合要求')
            return false
          }
        }

        //   大小
          if(this.maxSize){//限制大小需求不需要分片
            if(file.size > this.maxSize){
                 this.$message.error(`文件大小不能大于${this.getSize(this.maxSize)}`)
                 return false
            }
            this.ifSplitFlag = false
          }else{//无限制大小，则根据文件大小进行分片上传
            console.log('分片====')
            if(file.size > this.chunkSize){//分片
              this.ifSplitFlag = true
            }else{//不分片
              this.ifSplitFlag = false
            }
            return true;
          }
          return true;
      },
    //   单文件上传
    singleLoad(file){
        let formData = new FormData()
        formData.append('file',file.file)
        formData.append('storageType','local')
        let config = {
          headers:{
              'Content-Type':'multipart/form-data',
              'GatewayToken':'emp6bDpnYXRld2F5OjEyMzQ1Ng==',
              'Authorization': 'bearer ' + getToken()
              }
        };
        axios.post(this.url,formData,config)
          .then(response=>{
            console.log('上传====',response);
            // if(response.status == 200)
            const req = this.checkStatus(response.data.code,response.data.message)
            if(req){
                let data = response.data.data
                this.$emit('toGetSuccessData',{'fileId':data.fileId,'fileName':file.file.name})
                file.onSuccess(data)
            }
            console.log('req===',req,this.fileList)
        })

    },
    // 分片上传
    splitUpload(file){
      console.log('splitUpload',file)
      let tempFile = file.file
      this.tempFile = tempFile
      this.fileSize = tempFile.size
      this.fileName = tempFile.name
      let chunk = tempFile.slice(0, this.firstChunkSize)
      this.sliceUpload(chunk,tempFile,file)
    },
    sliceUpload(chunk,file,splitFiles){
      let formData = new FormData()
      formData.append('fileName',this.fileName)
      formData.append('isSlice',1)
      formData.append('storageType','local')
      formData.append('fileSize',this.fileSize)
      formData.append('sliceSeq',this.sliceSeq)
      formData.append('fileId',this.fileId)
      formData.append('file',chunk)
       let config = {
          headers:{
              'Content-Type':'multipart/form-data',
              'GatewayToken':'emp6bDpnYXRld2F5OjEyMzQ1Ng==',
              'Authorization': 'bearer ' + getToken()
              }
        };
        axios.post(this.splitUrl,formData,config)
          .then(response=>{
            console.log('分片上传====',response);
            let data  = response.data.data
            if(data&&data.fileId){
              this.fileId = data.fileId
              this.sliceSeq = data.sliceSeq + data.sliceSize
              if(this.sliceSeq == this.fileSize){
                console.log('所有分片上传完毕')
                this.$message.success('上传成功')
                // this.$emit('upLoadSuccess',data)
                this.$emit('toGetSuccessData',{'fileId':data.fileId,'fileName': this.fileName})
                splitFiles.onSuccess(data)
              }else{
                let surplusSize = this.fileSize - this.sliceSeq //剩余未上传的大小
								let nextChunk = null
								if(surplusSize > this.chunkSize){
									nextChunk = this.tempFile.slice(this.sliceSeq, this.sliceSeq + this.chunkSize)
								}else{
									nextChunk = this.tempFile.slice(this.sliceSeq, this.fileSize)
								}
                this.sliceUpload(nextChunk,file)
              }
            }else{
              this.checkStatus(response.data.code,response.data.message)
              this.beforeRemove(file)
            }
        })
    },
    //请求状态返回
    checkStatus(code,message){
        let errMessage = message?message:'系统内部异常'
        let res = true
        let resCode = code?code:200
        switch(resCode){
            case 401:
                this.$message.error('很抱歉，无访问权限')
                return res = false
                break
            case 404:
                this.$message.error('很抱歉，资源未找到')
                return res = false
                break
            case 403:
                this.$message.error('很抱歉，您暂无该操作权限')
                return res = false
                break
            case 401:
                this.$confirm('登录已过期，请重新登录', '温馨提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                    }).then(() => {
                        //跳转登录页，自行修改
                        router.push('/login')
                    }).catch(() => {
                        this.$message({
                            type: 'info',
                            message: '已取消'
                        });
                });
                break
            case 500:
                 this.$message.error(errMessage)
                 return res = false
                 break
            case resCode:
                this.$message.success('上传成功')
                return res = true
                break

        }
    },
      handleSuccess(response, file, fileList){
          console.log('handleSuccess===response, file, fileList',response, file, fileList)
          let newFileList = []
          newFileList = fileList.map(item => {
            let fileId = item.response ? item.response.fileId : item.fileId
            return{
              name:item.name,
              url: item.url,
              uid: item.uid,
              fileId: fileId
            }
          })
          // this.$emit('upLoadSuccess',{response,fileList})
           this.$emit('upLoadSuccess',{response,newFileList})
      },
    handleRemove(file, fileList) {
      console.log('handleRemove',file, fileList);
       this.$emit('removeFileList', fileList)
    },
    handlePreview(file) {
      console.log(file);
      if(this.uploadType != 'file'){//预览
         this.dialogVisible = true
        this.dialogFile = file
      }else{//下载文件
        // console.log(file)
        this.$emit('previewLoadFile',file)
        // let link = document.createElement("a");
        // link.style.display = "none";
        // link.href = process.env.VUE_APP_BASE_API + 'file/api/download/'+file.fileId;
        // link.setAttribute("download", file.name); //fileName下载后的文件名
        // document.body.appendChild(link);
        // link.click();
        window.open(process.env.VUE_APP_BASE_API + 'file/api/download/'+file.fileId, '_blank');
      }

    },
    handleExceed(files, fileList) {
        console.log('handleExceed====')
      this.$message.warning(`最多仅可上传${this.limit}个文件`);
    },
    beforeRemove(file, fileList) {
      console.log('beforeRemove',file,fileList)
      return this.$confirm(`确定移除 ${file.name}？`).then(res => {
        const index = this.fileList.findIndex((item) => item.uid === file.uid)
        this.$emit('removeFile', index)
      })
    },
  },
};
</script>

<style lang="scss" scoped>
.upload_btn {
  width: 100%;
  height: 100%;
  position: relative;
  text-align: center;

  .el-icon-plus {
    font-size: 40px;
    color: #999;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
  }
}
::v-deep {
  .el-upload-list--picture-card .el-upload-list__item-actions {
    z-index: 1;
  }
}
.dialog-content {
  text-align: center;
  height: 60vh;
  img,
  video {
    width: 100%;
    height: 100%;
  }
}
::v-deep .el-upload-list__item.is-success .el-upload-list__item-status-label{
  display: none;
}

</style>
